package com.example.system.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.starter.mybatis.configure.MybatisProperties;
import com.example.starter.mybatis.util.PageUtil;
import com.example.starter.util.ExceptionUtil;
import com.example.system.convert.TenantConvert;
import com.example.system.dto.TenantDto;
import com.example.system.dto.TenantParam;
import com.example.system.entity.Role;
import com.example.system.entity.Tenant;
import com.example.system.entity.User;
import com.example.system.mapper.RoleMapper;
import com.example.system.mapper.TenantMapper;
import com.example.system.mapper.UserMapper;
import com.example.system.service.ITenantService;
import com.example.system.vo.TenantVo;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 *
 * @author 王令
 * @since 2022-10-21
 */
@Service
@RequiredArgsConstructor
public class TenantServiceImpl extends ServiceImpl<TenantMapper, Tenant> implements ITenantService {

    private static final String defaultAdmin = "defaultAdmin";

    private final MybatisProperties properties;
    private final RoleMapper roleMapper;
    private final UserMapper userMapper;


    @Transactional
    @Override
    public void create(TenantDto tenantDto) {
        Tenant tenant = TenantConvert.INSTANCE.toTenant(tenantDto);
        Tenant one = baseMapper.selectOne(Wrappers.<Tenant>lambdaQuery().eq(Tenant::getTenantId, tenant.getTenantId()));
        if (one != null) {
            throw ExceptionUtil.wrap("租户id已存在");
        }
        this.save(tenant);
        roleMapper.addAdminRoleWithTenant(tenant.getTenantId(), defaultAdmin);
    }

    @Override
    public void update(TenantDto tenantDto) {
        Tenant tenant = TenantConvert.INSTANCE.toTenant(tenantDto);
        Tenant oldTenant = baseMapper.selectById(tenant.getId());
        if (oldTenant == null) {
            throw ExceptionUtil.wrap("租户不存在");
        }
        if (!StrUtil.equals(oldTenant.getTenantId(), tenant.getTenantId())) {
            throw ExceptionUtil.wrap("租户id不能修改");
        }
        this.updateById(tenant);
    }

    @Transactional
    @Override
    public void grantAuthority(String tenantId, List<Long> authoritiesId) {
        baseMapper.removeWithAuthorityJoins(tenantId);
        if (ObjUtil.isNotEmpty(authoritiesId)) {
            baseMapper.addWithAuthorityJoins(tenantId, authoritiesId);
        }
    }

    @Transactional
    @Override
    public void setUpAdmin(String tenantId, String username) {
        // 创建默认管理员_拥有租户全部权限
        List<Long> authorityIds = baseMapper.listAuthorityIdByTenantId(tenantId);
        Role role = roleMapper.findByTenantIdAndCode(tenantId, defaultAdmin);
        roleMapper.removeWithAuthorityJoins(role.getId());
        if (ObjUtil.isNotEmpty(authorityIds)) {
            roleMapper.addWithAuthorityJoins(role.getId(), authorityIds);
        }
        User user = userMapper.findByTenantIdAndUsername(tenantId, username);
        userMapper.removeWithRoleJoins(user.getId());
        userMapper.addWithRoleJoins(user.getId(), ListUtil.of(role.getId()));
    }

    @Override
    public Page<TenantVo> listWithPagination(Pageable pageable, TenantParam param) {
        return baseMapper.listWithPaginationExcludeMaster(PageUtil.getPage(pageable), properties.getMaster(), param);
    }

    @Override
    public List<Long> listAuthorityIdByTenantId(String tenantId) {
        return baseMapper.listAuthorityIdByTenantId(tenantId);
    }

}
